package com.dhy.cp

import java.io.File
import javax.annotation.processing.Messager
import javax.annotation.processing.ProcessingEnvironment
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.TypeElement
import javax.tools.Diagnostic

internal class ComponentProcessor {
    private lateinit var messager: Messager
    private lateinit var moduleName: String
    private lateinit var componentFile: File
    private lateinit var componentsFile: File
    private lateinit var annotation: String
    private lateinit var packageName: String

    fun init(processingEnv: ProcessingEnvironment) {
        messager = processingEnv.messager
        val moduleName = processingEnv.options[OPTION_MODULE_NAME]
        val annotation = processingEnv.options[OPTION_ANNOTATION]
        val dir = processingEnv.options[OPTION_JAVA_DIR]
        if (moduleName.isNullOrEmpty() || annotation.isNullOrEmpty() || dir.isNullOrEmpty()) return logError()
        this.moduleName = moduleName.replaceFirstChar { it.uppercase() }
        this.annotation = annotation
        packageName = annotation.substring(0, annotation.lastIndexOf("."))
        val path = annotation.replace(".", "/")
        componentFile = File(dir, "$path.java")
        componentsFile = File(dir, "${path}s.java")
    }

    private fun logError() {
        val msg = """
            请在应用中增加如下设置！
            //annotationProcessor
            android {
                defaultConfig {
                    javaCompileOptions {
                        annotationProcessorOptions {
                            arguments = [
                                    'moduleName'    : project.name,
                                    'annotation'    : 'com.dhy.demo.Component'
                                    'java_dir'      : rootProject.file('app/src/main/java').toString()
                            ]
                        }
                    }
                }
            }
            
            //kotlin-kapt
            kapt {
                arguments {
                    arg("moduleName", project.name)
                    arg("annotation", 'com.dhy.demo.Component')
                    arg("java_dir", rootProject.file('app/src/main/java').toString())
                }
            }
  """.trimIndent()
        messager.printMessage(Diagnostic.Kind.ERROR, msg)
        throw RuntimeException()
    }

    fun getSupportedAnnotationTypes() = setOf(annotation)

    fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
        if (annotations.isEmpty()) return true

        val elements = roundEnv.getElementsAnnotatedWith(annotations.first()).filterIsInstance(TypeElement::class.java)
        if (elements.isEmpty()) return true
        val classes: MutableList<String> = mutableListOf()
        elements.forEach {
            val type = it.asType().toString()
            classes.add(type)
        }
        ComponentProcessorUtil.update(packageName, componentsFile, componentFile, moduleName, classes)
        return true
    }

    private fun log(msg: String) {
        messager.printMessage(Diagnostic.Kind.NOTE, "${msg}\r\n")
    }
}

const val OPTION_MODULE_NAME = "moduleName"
const val OPTION_ANNOTATION = "annotation"
const val OPTION_JAVA_DIR = "java_dir"